#include "llcc68.h"

void t_lc68_destroy(llcc68_handle_t *ctx)
{
    if (ctx != NULL)
    {
        LC68_FREE(ctx);
    }
}
void llcc68_reset(llcc68_handle_t *ctx)
{
    ctx->pwrite(ctx->hw_gpio->reset_port, ctx->hw_gpio->reset_pin, T_LC68_PIN_RESET);
    ctx->delay_ms(10);
    ctx->pwrite(ctx->hw_gpio->reset_port, ctx->hw_gpio->reset_pin, T_LC68_PIN_SET);
    ctx->delay_ms(10);
}

llcc68_handle_t *t_lc68_create( 
    void *arg,
    lc68_pincfg_f cfgout_func,
    lc68_pincfg_f cfgin_func,
    lc68_delay_f delay_func,
    lc68_write_f i2c_w_func,
    lc68_read_f i2c_r_func,
    lc68_spi_write_read_f spi_write_read_func,
    const lc68_gpio_t *hw_gpio)
{
    // 1. 分配内存
    llcc68_handle_t *ctx = (llcc68_handle_t *)LC68_MAlLOC(sizeof(llcc68_handle_t));
    if (ctx == NULL)
    {
        LC68_DEBUG("LLCC68 create failed: malloc returned NULL\r\n");
        return NULL;
    }

    // 2. 清空内存
    memset(ctx, 0, sizeof(llcc68_handle_t));

    // 3. 赋值参数
    ctx->arg = arg;
    ctx->cfg_out = cfgout_func;
    ctx->cfg_in = cfgin_func;
    ctx->cfg_irq = NULL; // 初始化中断配置函数为NULL
    ctx->delay_ms = delay_func;
    ctx->pwrite = i2c_w_func;
    ctx->pread = i2c_r_func;
    ctx->spi_write_read = spi_write_read_func;
    ctx->hw_gpio = hw_gpio;
    ctx->rev_cb = NULL; // 初始化回调函数为NULL
    // 4. 初始化GPIO状态
    ctx->cfg_in(ctx->hw_gpio->busy_port, ctx->hw_gpio->busy_pin);
    //ctx->cfg_out(ctx->hw_gpio->reset_port, ctx->hw_gpio->reset_pin);
    // 初始状态：RESET引脚拉高
    ctx->pwrite(ctx->hw_gpio->reset_port, ctx->hw_gpio->reset_pin, T_LC68_PIN_SET);
    // 5. 返回创建的上下文
    LC68_DEBUG("LLCC68 create success\r\n");
    // 6. 复位芯片
    llcc68_reset(ctx);
    return ctx;
}

void llcc68_register_irq_callback(llcc68_handle_t *ctx, receive_callback cb)
{
    ctx->rev_cb = cb;
}
void llcc68_irq_handler(llcc68_handle_t *ctx)
{
    if (ctx->rev_cb)
    {
        uint8_t dummy_buf[32] = {0}; // 举例
        ctx->rev_cb(0xFF, dummy_buf, 32);  // 自定义 type、buf
    }
}


lc68_err_t llcc68_wait_busy_low(llcc68_handle_t *ctx, uint32_t timeout_ms)
{
    uint32_t tick = 0;
    while (ctx->pread(ctx->hw_gpio->busy_port, ctx->hw_gpio->busy_pin))
    {
        ctx->delay_ms(1);
        tick++;
        if (tick >= timeout_ms)
        {
            LC68_DEBUG("LLCC68 busy timeout\r\n");
            return LC68_ERR_TIMEOUT;
        }
    }
    return LC68_OK;
}

lc68_err_t llcc68_write_cmd(llcc68_handle_t *ctx, uint8_t cmd, const uint8_t *data, uint16_t len)
{
    uint8_t buf[256];

    if (len + 1 > sizeof(buf)) return LC68_ERR_INT;

    buf[0] = cmd;
    if (data && len > 0)
    {
        memcpy(&buf[1], data, len);
    }

    lc68_err_t err = llcc68_wait_busy_low(ctx, 100);
    if (err != LC68_OK) return err;

    ctx->spi_write_read(buf, len + 1, NULL, 0);

    return llcc68_wait_busy_low(ctx, 100);
}

lc68_err_t llcc68_read_cmd(llcc68_handle_t *ctx, uint8_t cmd, uint8_t *rx_buf, uint16_t rx_len)
{
    uint8_t tx[2] = { cmd, 0x00 };  // second byte is dummy
    lc68_err_t err = llcc68_wait_busy_low(ctx, 100);
    if (err != LC68_OK) return err;

    ctx->spi_write_read(tx, 2, rx_buf, rx_len);

    return llcc68_wait_busy_low(ctx, 100);
}

lc68_err_t llcc68_init(llcc68_handle_t *ctx)
{
    llcc68_reset(ctx);
    lc68_err_t err = llcc68_wait_busy_low(ctx, 100);
    if (err != LC68_OK) return err;

    // 示例：获取版本号 (CMD = 0xC0, 假设版本长度 4 字节)
    uint8_t version[4] = {0};
    err = llcc68_read_cmd(ctx, 0xC0, version, 4);
    if (err == LC68_OK)
    {
        LC68_DEBUG("LLCC68 Version: %02X %02X %02X %02X\r\n", version[0], version[1], version[2], version[3]);
    }

    return err;
}
